#  弹球 游戏  自定义函数  循环 模块
from tkinter import *  # 导入动画模块
import time    # 导入时间模块
import random  # 导入随机模块
# 自定义函数 一个 球 类

class Ball():
    def __init__(self,canvas,paddle,score,color): # 初始化功能
        self.canvas= canvas   # 外面画布 全局变量canvas 传递参数  self.canvas 画布
        self.paddle = paddle
        self.score = score
        self.id = canvas.create_oval(0,0,50,50, fill = color)   # 创建了一个小球 x1= 0 y1 =0 x2 =10,y2 =10 赋值给self.id3
        self.canvas.move(self.id,400,200)    #初始化 移动到 400,200 坐标
        level = [-7,-5,-3,-1,1,3,5,7,9]
        self.x = random.choice(level)
        self.y = random.choice(level)
        self.hit_bottom = False   # ball.hit_bottom  小球开关
    def draw(self):
        self.canvas.move(self.id, self.x , self.y ) # self.x 水平, self.y 垂直
        # 碰撞 坐标  获取小球的坐标
        pos = canvas.coords(self.id)  # 获取小球的坐标 赋值给 pos =  [x1,y1,x2,y2]
        if pos[3] >= 600:   # 小球底部 当y2 不断往下 递增
            #self.y = -3
            self.hit_bottom = True
        if pos[1] <= 0:    #  小球顶部 y1  不断往上 减少到0时 改变方向
            self.y = 3
        if pos[0] <= 0:   # 小球的最左边  不断左移动  减少 到0  改变self.x 为正
            self.x = 3
        if pos[2] >= 800:
            self.x = -3
        if self.hit_paddle(pos) == True:
            self.y = -3
    # 球拍打到小球  小球弹起   判断满足小球弹起
    #  需要 小球的坐标  以及 球拍的坐标
    def hit_paddle(self,pos):  # 把小球坐标传进来 局部自定义函数里  要把 球拍的参数传进来 球拍 外部类
        paddle_pos = self.canvas.coords(self.paddle.id)   # 获取了球拍的坐标 命名为 paddle_pos
        if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:  # 垂直方向  移动状态 临界静止状态
            if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:  # 水平方向  区间内
                self.score.hit()
                self.x = self.x + self.paddle.x
                return True
        return False
       # print("小球的坐标+",pos,"球拍的坐标+",paddle_pos)
      #  同时满足水平方向 和垂直方向的条件 才能被击中 小球的Y2 往下 移动 球拍的Y1

class Paddle():
    def __init__(self, canvas, color):  # 初始化功能
        self.canvas = canvas  # 外面画布 全局变量canvas 传递参数  self.canvas 画布
        self.id = canvas.create_rectangle(0, 0, 300, 50, fill=color)  # 创建了一个小球 x1= 0 y1 =0 x2 =10,y2 =10 赋值给self.id3
        self.canvas.move(self.id, 300, 450)  # 初始化 移动到 400,200 坐标
        self.x = 0
        self.game_start = False   # 游戏开关  关
        self.canvas.bind_all('<KeyPress-Left>',self.turn_left)  # 监听所有键盘左键  执行 turn_left
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)  # 监听所有键盘左键  执行 turn_left
        self.canvas.bind_all('<KeyPress-F1>',self.start)  # 触发后面的函数
    def start(self,evt):
        self.game_start = True

    def draw(self):
        self.canvas.move(self.id, self.x , 0 ) # self.x 水平, self.y 垂直
        # 碰撞 坐标  获取小球的坐标
        pos = canvas.coords(self.id)  # 获取球拍的坐标 赋值给 pos =  [x1,y1,x2,y2]
        if pos[0] <= 0:   # 小球的最左边  不断左移动  减少 到0  改变self.x 为正
            self.x = 3
        if pos[2] >= 800:
            self.x = -3
    # 添加球拍向左移动的函数
    def turn_left(self,evt): # event 事件  触发
        self.x = -5
    def turn_right(self,evt):
        self.x = 5

class Score():
    def __init__(self,canvas,color):
        self.canvas = canvas
        self.score = 0  # 初始化 分数 为 0
        self.id = self.canvas.create_text(750,50,text = self.score,font=("Arial",30), fill = color)  # 创建分数  赋值给 self.id  分数 变量
    # itemconfig 配置
    def hit(self):  # 自定义击打函数
        self.score = self.score + 100   # 每次击打一次 加一分
        self.canvas.itemconfig( self.id, text = self.score)

tk = Tk()  # 定义好的动画模块  借用 实例化  创建一个动画模块 tk 用 Tk 函数 实例化
tk.title("人生的第一个自己开发的游戏")  # 所有编程代码 英文输入法
# 实例化一个画布  #
canvas = Canvas(tk, width = 800, height = 600) # 实例化一个画布 宽为500 高为400 绑定在 tk 动画模块
canvas.pack()
paddle = Paddle(canvas, "blue")
score = Score(canvas,"red")
ball = Ball(canvas,paddle,score,"red")
game_over_text = canvas.create_text(400, 300, text="Game Over", font=("Arial", 30),state= 'hidden')


#ball2 = Ball(canvas,"yellow")
while 1:
    if ball.hit_bottom == False and paddle.game_start == True :   # 游戏开始 当小球没碰到 底部在时候  允许小球移动
        ball.draw()
        paddle.draw()
    if ball.hit_bottom == True:
        canvas.itemconfig(game_over_text, state = 'normal')
 #   ball2.draw()
    tk.update_idletasks()    # 更新任务栏
    tk.update()  # 刷新tk 动画
    time.sleep(0.01) #